package com.wf.netty.pipeline;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 功能描述
 *
 * @author wf
 * @since 2022/5/24
 */
public class Handlers {
    private static final Logger LOGGER = LoggerFactory.getLogger(Handlers.class);

    static class InHandlerA extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            LOGGER.info("Handler A 被调用");
            super.channelRead(ctx, msg);
        }
    }

    static class InHandlerB extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            LOGGER.info("Handler B 被调用");
            super.channelRead(ctx, msg);
        }
    }

    static class InHandlerC extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            LOGGER.info("Handler C 被调用");
            super.channelRead(ctx, msg);
        }
    }

    static class InChannelHandlerInitializer extends ChannelInitializer<EmbeddedChannel> {

        @Override
        protected void initChannel(EmbeddedChannel ch) throws Exception {
            ch.pipeline().addLast(new InHandlerA());
            ch.pipeline().addLast(new InHandlerB());
            ch.pipeline().addLast(new InHandlerC());
        }
    }

    static class OutChannelHandlerA extends ChannelOutboundHandlerAdapter {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
            LOGGER.info("OutChannelHandlerA 被回调");
            super.write(ctx, msg, promise);
        }
    }

        static class OutChannelHandlerB extends ChannelOutboundHandlerAdapter {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
            LOGGER.info("OutChannelHandlerB 被回调");
            super.write(ctx, msg, promise);
        }
    }

        static class OutChannelHandlerC extends ChannelOutboundHandlerAdapter {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
            LOGGER.info("OutChannelHandlerC 被回调");
            super.write(ctx, msg, promise);
        }
    }


    @Test
    public void testInBound() {
        EmbeddedChannel embeddedChannel = new EmbeddedChannel(new InChannelHandlerInitializer());
        ByteBuf buffer = Unpooled.buffer();
        buffer.writeInt(1);
        // 向通道写入入站报文或数据包
        embeddedChannel.writeInbound(buffer);
    }

    @Test
    public void testOutBound() {
        ChannelInitializer<EmbeddedChannel> channelInitializer = new ChannelInitializer<EmbeddedChannel>() {
            @Override
            protected void initChannel(EmbeddedChannel ch) throws Exception {
                ch.pipeline().addLast(new OutChannelHandlerA());
                ch.pipeline().addLast(new OutChannelHandlerB());
                ch.pipeline().addLast(new OutChannelHandlerC());
            }
        };

        EmbeddedChannel outChannel = new EmbeddedChannel(channelInitializer);
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeInt(1);
        // 向通道写入出站报文或数据包
        outChannel.writeOutbound(byteBuf);
        outChannel.close();
    }


}
